#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "cr.h"
/*Test #include "cw.h"*/
struct scintrar
{
	char* line;
	char* name;
        int arist_cant;
        int vector_cant;
        Bool arr;
	Bool eof;
};

cintrar
cra_create (void)
{
        cintrar cra=NULL;
        cra = (cintrar) calloc (1,sizeof(struct scintrar));
        if (cra==NULL)
        {
                warn(ERRFMT,"cra_create : Hubo un error al crear la cinta\n",__LINE__);
        }else{
		cra -> line = NULL;
		cra -> name = NULL;
		cra -> arr = FALSE;
		cra -> eof = FALSE;
        }
	return cra;
	
}

void
cra_arr (cintrar cra)
{
	size_t n;
        if (cra==NULL)
        {
                err(EXIT_FAILURE,ERRFMT,"cra_arr : Hubo un error al crear la cinta\n",__LINE__);
        }
	if (stdin==NULL){
		cra = cra_destroy (cra);
		err(EXIT_FAILURE,ERRFMT,"cra_arr : No hay datos en la entrada estandar\n",__LINE__);
	}
	
	if ( (-1 == getline(&(cra -> line),&n,stdin )) || (2 != sscanf( cra -> line," # %d %d\n",&(cra -> vector_cant),&(cra -> arist_cant))) ) {
		cra = cra_destroy (cra);
		err(EXIT_FAILURE,ERRFMT,"cra_arr: Formato Dot no compatible\n",__LINE__);
		
	}
	if (cra ->line != NULL){
		free(cra -> line);
		cra -> line = NULL;
	}
	if (-1 != getline(&(cra -> line),&n,stdin )){
		cra -> name = (char*) calloc ( strlen ( cra ->line)+1 , sizeof(char));
	}
	if  (cra -> name == NULL){
		cra = cra_destroy (cra);
		err(EXIT_FAILURE,ERRFMT,"cra_arr: No hay suficiente memoria\n",__LINE__);
	}
	if((1 != sscanf( cra -> line,"graph %s {", (cra -> name)))||(cra -> line [strlen ( cra ->line)] == '}') ){
		cra = cra_destroy (cra);
		err(EXIT_FAILURE,ERRFMT,"cra_arr: Formato Dot no compatible\n",__LINE__);
	}	
	
        cra -> arr = TRUE;
	cra_av(cra);
}

Bool
cra_fin (cintrar cra)
{
        if ((cra -> arr)!= TRUE){
		cra = cra_destroy (cra);
                err(EXIT_FAILURE,ERRFMT,"cra_fin : La Cinta no fue arrancada\n",__LINE__);
	}
        return (cra -> eof);
}

void
cra_av (cintrar cra)
{
	size_t n;
        if (cra_fin(cra)){
		err(EXIT_FAILURE,ERRFMT,"cra_av : Final de Linea\n",__LINE__);
	}
	
	if (cra ->line != NULL){
		free(cra -> line);
		cra -> line = NULL;
	}
	if(-1 == getline(&(cra -> line),&n,stdin )){
		cra = cra_destroy (cra);
		err(EXIT_FAILURE,ERRFMT,"cra_av : Formato Dot no compatible\n",__LINE__);
	}else{
		cra -> eof = (cra -> line [0] == '}');
 	}
}

arista
cra_elec (cintrar cra)
{
	int node1 , node2 , weight;
	char end;
        if (cra_fin(cra)){
		err(EXIT_FAILURE,ERRFMT,"cra_elec : Final de Linea\n",__LINE__);
	}
	if((4 == sscanf(cra -> line,"\n %d -- %d [ label = %d ] %c", &node1 , &node2, &weight, &end))){
		if ( end != ';'){
			cra = cra_destroy (cra);
			err(EXIT_FAILURE,ERRFMT,"cra_create : Formato Dot no compatible\n",__LINE__);
			
		}
	}
        return arista_fromNodes (node1 , node2 , weight);
}

int
cra_cantvert(const cintrar cra){
	return cra -> vector_cant;
}

int
cra_cantaris(const cintrar cra){ 
	return cra -> arist_cant;
}

char*
cra_name(cintrar cra){
	char* ret = NULL;
	ret = (char*) calloc ( strlen(cra->name) + 1, sizeof(char));
	if  ( ret== NULL){
		cra = cra_destroy (cra);
		err(EXIT_FAILURE,ERRFMT,"cra_arr: No hay suficiente memoria\n",__LINE__);
	}
	strncpy ( ret , cra -> name, strlen(cra->name)+1);
	return ret;
}

cintrar
cra_destroy (cintrar cra)
{
	if(cra -> name != NULL){
		free (cra -> name);
		cra -> name = NULL;
	}
	if(cra -> line != NULL){
		free (cra -> line);
		cra -> line = NULL;
	}	
        free(cra);
        cra = NULL;
        return cra ;
}
/*Test
int main (void){
        cintrar cra = NULL;
	cintwar cwa = NULL;
	arista ar = NULL;
	char* name = NULL;
        cra = cra_create();
        if (cra==NULL)
        {
                warn(ERRFMT,"main: Hubo un error al crear la cinta\n",__LINE__);
                return 1;
        }
        cra_arr(cra);
	printf(" Nodos: %d, Aristas: %d\n", cra_cantvert(cra), cra_cantaris(cra));
	name = cra_name(cra);
	cwa = cwa_create(name);
	free (name);
	name = NULL;
	cwa_arr(cwa);
        while (!(cra_fin(cra))){
		ar = cra_elec(cra);
                cwa_insarbol(cwa ,ar);
		free (ar);
		ar = NULL;
                cra_av(cra);
        }
	cwa = cwa_destroy(cwa);
        cra = cra_destroy(cra);
        return 0;
}*/
